//
// Created by yuping.li@calmcar.com on 7/3/24.
//

#ifndef FIBER_SINGLE_THREAD_SCHEDULER_H
#define FIBER_SINGLE_THREAD_SCHEDULER_H

#include "task.hpp"
#include "platform/time.hpp"
#include <memory>
#include <vector>
#include <cstring>

class SingleThreadScheduler {
 public:
  explicit SingleThreadScheduler() = default;

  void scheduler() {
    //对所有Task进行初始化（申请栈，makecontext,保存调度器的context的指针）
    for (auto& task : tasks) {
      task->task_init(&context);
    }

    while (true) {
      if (tasks.empty()) {
        continue;
      }

      //找出最小过期时间任务的索引
      std::size_t index{0};
      int64_t min_next_run_time = INT64_MAX;
      for (std::size_t i=0; i<tasks.size(); ++i) {
        if (tasks[i]->get_next_run_time() < min_next_run_time) {
          min_next_run_time = tasks[i]->get_next_run_time();
          index = i;
        }
      }

      //计算next_run_time最小的任务(tasks[index])的过期时间（sleep_time）
      int64_t sleep_time = tasks[index]->get_next_run_time() - Time::instance().get_timestamp_ms();
      //如果过期时间<=1ms并且该任务是周期任务，切换到task并运行，task应在适当的时候主动执行task_yield放弃cpu返回当前断点
      if (sleep_time <= 0) {
        swap_context(&context, tasks[index]->get_entry_context());
        continue;
      }
    }
  }


  void add_task(std::unique_ptr<Task>&& task) {
    tasks.emplace_back(std::move(task));
  }

 protected:
  std::vector<std::unique_ptr<Task>> tasks{};
  lcontext_t context{};
};


#endif //FIBER_SINGLE_THREAD_SCHEDULER_H
